import java.util.Arrays;

//顺序表
public class myArrayList<E> {

    public Object[] arrays;//存放数据
    public int usedSize;//统计个数

    public static int initialCapacity = 5;//默认容量

    public myArrayList(){
        //创建同时定义大小
        arrays = new Object[initialCapacity];
    }

    private void add_capacity(Object[] arrays){
        //二倍扩容
        arrays = Arrays.copyOf(arrays,arrays.length * 2);
    }

    // 新增元素,默认在数组最后新增
    public void add(E data) {
        //1.添加元素前需要判断是否容量是否未满
        if(usedSize == arrays.length){
            //如果容量已满扩容
            add_capacity(arrays);
        }
        //2.增加元素
        arrays[usedSize] = data;

        usedSize++;//下次增加的下标

    }

    // 在 pos 位置新增元素
    public void add(int pos, E data) {
        //1.判断是否需要扩容
        if(usedSize == arrays.length){
            add_capacity(arrays);
        }
        //2.坐标的使用需要判断是否合法
        if(pos < 0 || pos > usedSize){
            throw new PosillegalException("坐标非法：" + pos);
        }
        //3.增加:将pos位置后面的元素往后移动，再增加
        for (int i = usedSize - 1;i <= pos;i--){
            arrays[usedSize] = arrays[usedSize + 1];
        }
        arrays[pos] = data;

        usedSize++;//元素+1

    }
    // 判定是否包含某个元素
    public boolean contains(E toFind) {
        //1.判断是否为空
        if(usedSize == 0) return false;

        //2.调用search方法
        int pos = search(toFind);

        //3.判断
        if(pos == -1) return false;
        else return true;
    }
    // 查找某个元素对应的位置
    private boolean isEmpty(){
        return usedSize == 0;
    }
    public int indexOf(E toFind) {
        //1.判断是否为空
        if(isEmpty()) return -1;
        //2.使用search
        return search(toFind);
    }
    // 获取 pos 位置的元素
    public E get(int pos) {
        //1.判断坐标是否合法
        if(pos < 0 || pos >= usedSize){
            throw new PosillegalException("坐标非法：" + pos);
        }
        //2.返回
        return (E)arrays[pos];
    }
    // 给 pos 位置的元素设为 value
    public void set(int pos, E value) {
        //1.判断坐标是否合法
        if(pos < 0 || pos >= usedSize){
            throw new PosillegalException("坐标非法："+ pos);
        }
        //2.考虑是否扩容
        if(usedSize == arrays.length){
            add_capacity(arrays);
        }
        //3.设置
        arrays[pos] = value;
    }
    //删除第⼀次出现的关键字key
    private int search(E toRemove){
        for (int i = 0; i < arrays.length; i++) {
            if(arrays[i] == toRemove){
                return i;
            }
        }
        return -1;
    }
    public void remove(E toRemove) {
        //1.遍历数组查询是否存在
        int pos = search(toRemove);
        if (pos == -1) {
            System.out.println(toRemove + "不存在该元素！");
            return;
        }
        //2.在指定下标开始，从前往后覆盖
        for (int i = pos; i < usedSize - 1; i++) {
            arrays[i] = arrays[i + 1];
        }
        //3.元素减一
        usedSize--;
    }
    // 获取顺序表⻓度
    public int size() {
        //返回usedSize,实际使用的长度
        return usedSize;
    }
    // 清空顺序表
    public void clear() {
        //数组中的元素是E类型（泛型），有可能是引用数据类型
        //需要将元素设置为null

        for (int i = 0; i < usedSize; i++) {
            arrays[i] = null;
        }
        //将数组引用设置为null
        arrays = null;
    }
    // 打印顺序表，注意：该⽅法并不是顺序表中的⽅法，为了⽅便看测试结果给出的
    public void display() {
        //1.判断是否为空
        if(usedSize == 0){
            return;//无需打印
        }
        //2.打印
        for (int i = 0; i < usedSize; i++) {
            System.out.print(arrays[i] + " ");
        }
        System.out.println();
    }

}
